unit Unit1;

{$mode objfpc}{$H+}

{
This file is part of Keulkulator.

Keulkulator is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Keulkulator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Keulkulator.  If not, see <http://www.gnu.org/licenses/>.
}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, Menus,
  ExtCtrls, ComCtrls, StdCtrls, Spin, LazHelpHTML, LCLIntf, Buttons, ECSwitch,
  math, UData, Unit2, Unit3;

type

  { TMainForm }

  TMainForm = class(TForm)
    BtMatEdit: TButton;
    CBMaterial: TComboBox;
    ECSwitch1: TECSwitch;
    EdFile: TEdit;
    EdHflx: TEdit;
    EdStrom: TEdit;
    EdLeistung: TEdit;
    FlSpStaerke: TFloatSpinEdit;
    FlSpmm: TFloatSpinEdit;
    FlSpAWG: TFloatSpinEdit;
    FlSpBreite: TFloatSpinEdit;
    FlSpSpannung: TFloatSpinEdit;
    FlSpWeg: TFloatSpinEdit;
    FlSpWiderstand: TFloatSpinEdit;
    FlSpDurchmesser: TFloatSpinEdit;
    GroupBox1: TGroupBox;
    HTMLBrowserHelpViewer1: THTMLBrowserHelpViewer;
    HTMLHelpDatabase1: THTMLHelpDatabase;
    Image1: TImage;
    Image2: TImage;
    Image3: TImage;
    Image4: TImage;
    Label1: TLabel;
    Label10: TLabel;
    Label11: TLabel;
    Label13: TLabel;
    Label14: TLabel;
    Label19: TLabel;
    LaOhmAb: TLabel;
    LaOhmHalb: TLabel;
    LaOhmAuf: TLabel;
    Label18: TLabel;
    LaWindAb: TLabel;
    LaWindHalb: TLabel;
    LaWindAuf: TLabel;
    Label15: TLabel;
    Label16: TLabel;
    Label17: TLabel;
    LaWindungen: TLabel;
    Label12: TLabel;
    LaLaenge: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    Label9: TLabel;
    MainMenu: TMainMenu;
    MDatei: TMenuItem;
    MBeenden: TMenuItem;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    MenuItem3: TMenuItem;
    MenuItem4: TMenuItem;
    MHilfe: TMenuItem;
    OpenDialog1: TOpenDialog;
    Panel1: TPanel;
    RaBSingle: TRadioButton;
    RaBDual: TRadioButton;
    RaBQuad: TRadioButton;
    SaveDialog1: TSaveDialog;
    Shape1: TShape;
    SpBSwitch: TSpeedButton;
    StatusBar1: TStatusBar;
    procedure BtMatEditClick(Sender: TObject);
    procedure CBMaterialChange(Sender: TObject);
    procedure ECSwitch1Change(Sender: TObject);
    procedure FlSpAWGChange(Sender: TObject);
    procedure FlSpBreiteChange(Sender: TObject);
    procedure FlSpDurchmesserChange(Sender: TObject);
    procedure FlSpmmChange(Sender: TObject);
    procedure FlSpSpannungChange(Sender: TObject);
    procedure FlSpStaerkeChange(Sender: TObject);
    procedure FlSpWegChange(Sender: TObject);
    procedure FlSpWiderstandChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure MBeendenClick(Sender: TObject);
    procedure MenuItem1Click(Sender: TObject);
    procedure MenuItem2Click(Sender: TObject);
    procedure MenuItem3Click(Sender: TObject);
    procedure MenuItem4Click(Sender: TObject);
    procedure RaBDualChange(Sender: TObject);
    procedure RaBQuadChange(Sender: TObject);
    procedure RaBSingleChange(Sender: TObject);
    procedure  CalculateWraps;
    procedure SpBSwitchClick(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  MainForm: TMainForm;
  Durchmesser, Drahtstaerke, FBreite, FStaerke, Wunschohm, Ohmm, Laenge,
    Wicklungszahl, Weg, Coils, vohm, vhohm, vpohm, Hflx,
    urip_u, urip_r, urip_i, urip_p : Float;
  vwraps, vhwraps, vpwraps : String;
  Flachdraht : Boolean;

implementation

{$R *.lfm}

{ TMainForm }

function AWGTomm(AWG : Integer) : Float;  // Umwandlung AWG (Gauge) in Millimeter
begin
  AWGTomm := 0.127 * (92 ** ((36 - AWG)/39));
end;

function mmToAWG(mm : Float) : Integer;  // Umwandlung Millimeter in AWG (Gauge)
var AW : Float;
begin
  AW := -39 * logn(92, (mm / 0.127)) + 36;
  mmToAWG := round(AW);
end;

function ohmpermeter(rho, d : Float) : Float;  // Errechnen Ohm/m
begin
  ohmpermeter := rho * (1 / (PI * (power(d,2) / 4)));
end;

function ohmpermeter_flat(rho, breite, staerke : Float) : Float; // Errechnen Ohm/m für Flachdraht
begin
  ohmpermeter_flat := rho * (1 / (breite * staerke));
end;

procedure TMainForm.CalculateWraps;  // Wicklungen berechnen

var
  Radius, Umfang, Wohm, pvh, pvg : Float;
  dz : Integer;

begin
  Wohm := Wunschohm * Coils;
  Laenge := Wohm * 1000 / Ohmm;
  Radius := Durchmesser / 2;
  Radius := Radius + Drahtstaerke;
  Umfang := 2 * pi * Radius;
  Wicklungszahl := (Laenge - Weg) / Umfang;
  dz := trunc(Wicklungszahl);

  vwraps := IntToStr(dz) + '.0';     // ganze Wicklung
  vhwraps := IntToStr(dz) + '.5';    // + halbe Wicklung
  vpwraps := IntToStr(dz+1) + '.0';  // ganze Wicklung + 1

  vohm := (Umfang * dz + Weg * 2) * Ohmm / 1000;
  pvh := (Umfang / 2) * Ohmm / 1000;
  vhohm := vohm + pvh;
  pvg := Umfang * Ohmm / 1000;
  vpohm := vohm + pvh + pvg;

  urip_r := (Umfang * Wicklungszahl + Weg * 2) * Ohmm / 1000;
  urip_r := urip_r / Coils;
  urip_i := urip_u / urip_r;
  urip_p := urip_u * urip_i;

  LaLaenge.Caption := FloatToStrF(Laenge,ffFixed,2,2);
  LaWindungen.Caption := FloatToStrF(Wicklungszahl,ffFixed,2,2);
  LaWindAb.Caption := vwraps;
  LaWindHalb.Caption := vhwraps;
  LaWindAuf.Caption := vpwraps;
  LaOhmAb.Caption := FloatToStrF(vohm,ffFixed,2,2) + ' Ω';
  LaOhmHalb.Caption := FloatToStrF(vhohm,ffFixed,2,2) + ' Ω';
  LaOhmAuf.Caption := FloatToStrF(vpohm,ffFixed,2,2) + ' Ω';
  EdStrom.Caption := FloatToStrF(urip_i,ffFixed,2,2);
  EdLeistung.Caption := FloatToStrF(urip_p,ffFixed,2,2);
  if urip_i >= 10.0 then
  begin
    Shape1.Pen.Color := clRed;
    Shape1.Brush.Color := clRed
  end
  else
    Shape1.Pen.Color := clGreen;
  Hflx := (urip_p*1000)/(2*PI*(Drahtstaerke/2)*Laenge);
  EdHflx.Caption := FloatToStrF(Hflx,ffFixed,4,0);
  if Hflx < 775 then
  begin
    Shape1.Pen.Color := RGBToColor(234, 190, 14);
    Shape1.Brush.Color := RGBToColor(234, 190, 14)
  end;
  if Hflx < 550 then
  begin
    Shape1.Pen.Color := clLime;
    Shape1.Brush.Color := clLime
  end;
  if Hflx < 325 then
  begin
    Shape1.Pen.Color := clAqua;
    Shape1.Brush.Color := clAqua
  end;
  if Hflx >= 775 then
  begin
    Shape1.Pen.Color := clRed;
    Shape1.Brush.Color := clRed
  end;
end;

procedure TMainForm.SpBSwitchClick(Sender: TObject); // Breite und Stärke tauschen
var ValTmp : Double;
begin
  ValTmp := FlSpBreite.Value;
  FlSpBreite.Value := FlSpStaerke.Value;
  FlSpStaerke.Value := ValTmp;
  CalculateWraps;
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  InitData;                      // Werte initialisieren
  CBMaterial.Items := materialien;
  Durchmesser := 3.0;
  Wunschohm := 0.5;
  if Flachdraht then
     Ohmm := ohmpermeter_flat(spezwid[0], 0.25, 0.12)
  else
    Ohmm := ohmpermeter(spezwid[0], 0.4);
  Drahtstaerke := 0.4;
  Weg := 1.0;
  Coils := 1.0;
  urip_u := 3.6;
  urip_i := 7.23;
  urip_p := 26.76;
  if urip_i >= 10.0 then
    EdStrom.Font.Color := clRed
  else
    EdStrom.Font.Color := clGreen;
  Flachdraht := false
end;

procedure TMainForm.MBeendenClick(Sender: TObject);
begin
  application.terminate;
end;

procedure TMainForm.MenuItem1Click(Sender: TObject);
var
  CoilSetup : TStringList;
  filename : string;
begin
  CoilSetup := TStringList.Create;
  CoilSetup.Add(CBMaterial.Items[CBMaterial.ItemIndex]);
  CoilSetup.Add(FloatToStrF(FlSpmm.Value,ffFixed,2,2));
  CoilSetup.Add(FloatToStrF(FlSpWiderstand.Value,ffFixed,2,2));
  CoilSetup.Add(FloatToStrF(FlSpDurchmesser.Value,ffFixed,2,2));
  CoilSetup.Add(FloatToStrF(FlSpWeg.Value,ffFixed,2,2));
  CoilSetup.Add(FloatToStrF(Coils,ffFixed,1,1));
  CoilSetup.Add(FloatToStrF(FlSpBreite.Value,ffFixed,2,2));
  CoilSetup.Add(FloatToStrF(FlSpStaerke.Value,ffFixed,2,2));
  if Flachdraht then
     CoilSetup.Add('f')
  else
    CoilSetup.Add('r');
  if SaveDialog1.Execute then
   begin
     if FileExists(SaveDialog1.FileName) then
       if MessageDlg('Datei überschreiben', 'Die Datei ' + ExtractFileName(SaveDialog1.FileName) + ' existiert bereits! Datei überschreiben?',
          mtConfirmation, [mbYes, mbNo],0) = mrYes then
          begin
            filename := SaveDialog1.Filename;
            CoilSetup.SaveToFile(filename);
            EdFile.Text := ExtractFileName(SaveDialog1.FileName)
          end;
     if not FileExists(SaveDialog1.FileName) then
     begin
       filename := SaveDialog1.Filename;
       CoilSetup.SaveToFile(filename);
       EdFile.Text := ExtractFileName(SaveDialog1.FileName)
     end;
   end;
   CoilSetup.Free;
end;

procedure TMainForm.MenuItem2Click(Sender: TObject);
var
  CoilSetup : TStringList;
  filename : string;
  Mater, mil, Widerst, Durchm, We, Cls, Bre, Stae : string;
  i : Integer;
begin
  CoilSetup := TStringList.Create;
  if OpenDialog1.Execute then
    begin
      filename := OpenDialog1.Filename;
      CoilSetup.LoadFromFile(filename);

      Mater := CoilSetup[0];
      mil := CoilSetup[1];
      Widerst := CoilSetup[2];
      Durchm := CoilSetup[3];
      We := CoilSetup[4];
      Cls := CoilSetup[5];
      if CoilSetup.Count < 7 then
        begin
          Bre := '0.25';
          Stae := '0.12';
          ECSwitch1.Checked := false;
          Flachdraht := false;
          Label3.Caption:='mm';
          Label4.Caption:='AWG';
          FlSpmm.Visible:=true;
          FlSpAWG.Visible:=true;
          FlSpBreite.Visible:=false;
          FlSpStaerke.Visible:=false;
          Drahtstaerke := FlSpmm.Value;
          Ohmm := ohmpermeter(spezwid[CBMaterial.ItemIndex], Drahtstaerke);
          ShowMessage('Alte Sicherungsdatei!');
        end
      else
        begin
          Bre := CoilSetup[6];
          Stae := CoilSetup[7];
          if CoilSetup[8] = 'f' then
            begin
              ECSwitch1.Checked := true;
              Flachdraht := true;
              Label3.Caption:='Breite';
              Label4.Caption:='Stärke';
              FlSpmm.Visible:=false;
              FlSpAWG.Visible:=false;
              FlSpBreite.Visible:=true;
              FlSpStaerke.Visible:=true;
              FBreite := FlSpBreite.Value;
              FStaerke := FlSpStaerke.Value;
              Ohmm := ohmpermeter_flat(spezwid[CBMaterial.ItemIndex], FBreite, FStaerke);
            end
          else
          begin
            ECSwitch1.Checked := false;
            Flachdraht := false;
            Label3.Caption:='mm';
            Label4.Caption:='AWG';
            FlSpmm.Visible:=true;
            FlSpAWG.Visible:=true;
            FlSpBreite.Visible:=false;
            FlSpStaerke.Visible:=false;
            Drahtstaerke := FlSpmm.Value;
            Ohmm := ohmpermeter(spezwid[CBMaterial.ItemIndex], Drahtstaerke);
          end;
        end;
      for i := 0 to materialien.Count -1 do
        if Mater = materialien[i] then
        begin
          CBMaterial.Text := materialien[i];
          CBMaterial.ItemIndex := i;
        end;

      FlSpmm.value := MyStrToFloat(mil);
      FlSpAWG.Value := mmToAWG(FlSpmm.Value);
      FlSpBreite.Value := MyStrToFloat(bre);
      FlSpStaerke.Value := MyStrToFloat(stae);
      Drahtstaerke := FlSpmm.Value;
      FBreite := FlSpBreite.Value;
      FStaerke := FlSpStaerke.Value;
      if Flachdraht then
        Ohmm := ohmpermeter_flat(spezwid[CBMaterial.ItemIndex], FBreite, FStaerke)
      else
        Ohmm := ohmpermeter(spezwid[CBMaterial.ItemIndex], Drahtstaerke);
      FlSpWiderstand.Value := MyStrToFloat(Widerst);
      Wunschohm := FlSpWiderstand.Value;
      FlSpDurchmesser.Value := MyStrToFloat(Durchm);
      Durchmesser := FlSpDurchmesser.Value;
      FlSpWeg.Value := MyStrToFloat(We);
      Weg := FlSpWeg.Value;
      case trunc(MyStrToFloat(Cls)) of
        1: RaBSingle.Checked := true;
        2: RaBDual.Checked := true;
        4: RaBQuad.Checked := true;
      end;
      if RaBSingle.Checked then Coils := 1.0;
      if RaBDual.Checked then Coils := 2.0;
      if RaBQuad.Checked then Coils := 4.0;
      CalculateWraps;
      EdFile.Text := ExtractFileName(OpenDialog1.FileName)
    end;
  CoilSetup.Free;
end;

procedure TMainForm.MenuItem3Click(Sender: TObject);
begin
  FUeber.ShowModal;
end;

procedure TMainForm.MenuItem4Click(Sender: TObject);
begin
  OpenURL('docs/help.html');
end;

procedure TMainForm.RaBDualChange(Sender: TObject);
begin
  if RaBSingle.Checked then Coils := 1.0;
  if RaBDual.Checked then Coils := 2.0;
  if RaBQuad.Checked then Coils := 4.0;
  CalculateWraps;
end;

procedure TMainForm.RaBQuadChange(Sender: TObject);
begin
  if RaBSingle.Checked then Coils := 1.0;
  if RaBDual.Checked then Coils := 2.0;
  if RaBQuad.Checked then Coils := 4.0;
  CalculateWraps;
end;

procedure TMainForm.RaBSingleChange(Sender: TObject);
begin
  if RaBSingle.Checked then Coils := 1.0;
  if RaBDual.Checked then Coils := 2.0;
  if RaBQuad.Checked then Coils := 4.0;
  CalculateWraps;
end;

procedure TMainForm.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  application.terminate;
end;

procedure TMainForm.FlSpAWGChange(Sender: TObject);
begin
  FlSpmm.Value := AWGTomm(trunc(FlSpAWG.Value));
  Drahtstaerke := FlSpmm.Value;
  Ohmm := ohmpermeter(spezwid[CBMaterial.ItemIndex], Drahtstaerke);
  CalculateWraps;
end;

procedure TMainForm.FlSpBreiteChange(Sender: TObject);
begin
  FBreite := FlSpBreite.Value;
  FStaerke := FlSpStaerke.Value;
  Ohmm := ohmpermeter_flat(spezwid[CBMaterial.ItemIndex], FBreite, FStaerke);
  CalculateWraps;
end;

procedure TMainForm.FlSpDurchmesserChange(Sender: TObject);
begin
  Durchmesser := FlSpDurchmesser.Value;
  CalculateWraps;
end;

procedure TMainForm.FlSpmmChange(Sender: TObject);
begin
  FlSpAWG.Value := mmToAWG(FlSpmm.Value);
  Drahtstaerke := FlSpmm.Value;
  Ohmm := ohmpermeter(spezwid[CBMaterial.ItemIndex], Drahtstaerke);
  CalculateWraps;
end;

procedure TMainForm.FlSpSpannungChange(Sender: TObject);
begin
  urip_u := FlSpSpannung.Value;
  CalculateWraps;
  EdStrom.Caption := FloatToStrF(urip_i,ffFixed,2,2);
  EdLeistung.Caption := FloatToStrF(urip_p,ffFixed,2,2);
  if urip_i >= 10.0 then
    Label13.Font.Color := clRed
  else
    Label13.Font.Color := clGreen
end;

procedure TMainForm.FlSpStaerkeChange(Sender: TObject);
begin
  FBreite := FlSpBreite.Value;
  FStaerke := FlSpStaerke.Value;
  Ohmm := ohmpermeter_flat(spezwid[CBMaterial.ItemIndex], FBreite, FStaerke);
  CalculateWraps;
end;

procedure TMainForm.FlSpWegChange(Sender: TObject);
begin
  Weg := FlSpWeg.Value;
  CalculateWraps;
end;

procedure TMainForm.FlSpWiderstandChange(Sender: TObject);
begin
  Wunschohm := FlSpWiderstand.Value;
  CalculateWraps;
end;

procedure TMainForm.CBMaterialChange(Sender: TObject);
begin
  FBreite := FlSpBreite.Value;
  FStaerke := FlSpStaerke.Value;
  if Flachdraht then
     Ohmm := ohmpermeter_flat(spezwid[CBMaterial.ItemIndex], FBreite, FStaerke)
  else
    Ohmm := ohmpermeter(spezwid[CBMaterial.ItemIndex], Drahtstaerke);
  CalculateWraps;
end;

procedure TMainForm.ECSwitch1Change(Sender: TObject);
begin
  if ECSwitch1.Checked then
  begin
    Flachdraht := true;
    Label3.Caption:='Breite';
    Label4.Caption:='Stärke';
    FlSpmm.Visible:=false;
    FlSpAWG.Visible:=false;
    FlSpBreite.Visible:=true;
    FlSpStaerke.Visible:=true;
    FBreite := FlSpBreite.Value;
    FStaerke := FlSpStaerke.Value;
    Ohmm := ohmpermeter_flat(spezwid[CBMaterial.ItemIndex], FBreite, FStaerke);
    SpBSwitch.Visible := true;
  end
  else
  begin
    Flachdraht := false;
    Label3.Caption:='mm';
    Label4.Caption:='AWG';
    FlSpmm.Visible:=true;
    FlSpAWG.Visible:=true;
    FlSpBreite.Visible:=false;
    FlSpStaerke.Visible:=false;
    Drahtstaerke := FlSpmm.Value;
    Ohmm := ohmpermeter(spezwid[CBMaterial.ItemIndex], Drahtstaerke);
    SpBSwitch.Visible := false;
  end;
  CalculateWraps;
end;

procedure TMainForm.BtMatEditClick(Sender: TObject);
begin
  MatEditor.ShowModal;
  CBMaterial.Items := materialien;
  CBMaterial.ItemIndex := 0;
  Durchmesser := 3.0;
  Wunschohm := 0.5;
  if Flachdraht then
     Ohmm := ohmpermeter_flat(spezwid[0], 0.25, 0.12)
  else
    Ohmm := ohmpermeter(spezwid[0], 0.4);
  Drahtstaerke := 0.4;
  FBreite := 0.25;
  FStaerke := 0.12;
  Weg := 1.0;
  Coils := 1.0;
  urip_u := 3.6;
  urip_i := 7.23;
  urip_p := 26.76;
  if urip_i >= 10.0 then
    EdStrom.Font.Color := clRed
  else
    EdStrom.Font.Color := clGreen;
  CalculateWraps;
end;

end.

